package com.fone.player.client;

/**
 * 
 * @author 刘昆  (liukun@100tv.com)
 * @since  2014-04-22
 */

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import retrofit.RestAdapter;
import retrofit.RestAdapter.LogLevel;
import retrofit.RetrofitError;
import retrofit.android.AndroidLog;
import retrofit.client.Response;
import retrofit.http.EncodedPath;
import retrofit.http.EncodedQuery;
import retrofit.http.Field;
import retrofit.http.FormUrlEncoded;
import retrofit.http.GET;
import retrofit.http.POST;
import retrofit.http.Query;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.Time;
import android.util.Log;

import com.fone.player.ApplicationManage;
import com.fone.player.activity.BaseActivity;
import com.fone.player.sns.UserInfoManager;
import com.fone.player.util.ActivityQueue;
import com.fone.player.util.Base64;
import com.fone.player.util.FoneUtil;
import com.fone.player.util.L;
import com.google.gson.Gson;

public class Request {

	public class CallbackAdapter<T> implements retrofit.Callback<T> {
		private final com.fone.player.client.Callback<T> callback;

		private static final int EXITLOGINSUCCESS = 0;
		private MyHandler mHandler = null;

		public CallbackAdapter(com.fone.player.client.Callback<T> callback) {
			this.callback = callback;
		}

		@Override
		public void success(T t, Response response) {

			// TODO 判断是否是异地登陆
			if (t instanceof Rst) {
				final Rst rst = (Rst) t;
				L.v(TAG, " success : ", t.toString());
				if (rst.result != 0 && rst.error != null && (rst.error.errorcode.equals("119") || rst.error.errorcode.equals("210"))) {
					if (mHandler == null) {
						mHandler = new MyHandler();
					}
					new Thread() {
						public void run() {
							UserInfoManager.saveLoginState(false);
							UserInfoManager.exitLogin();// 清除本地信息;
							mHandler.obtainMessage(EXITLOGINSUCCESS, rst).sendToTarget();
						};
					}.start();
					return;
				}
			}
			this.callback.onSuccess(t);
		}

		@Override
		public void failure(RetrofitError error) {

			Log.e("REST", error.toString());

			if (error.isNetworkError()) {
				this.callback.onFailure(new Error(true, 0, null));
			} else {
				this.callback.onFailure(new Error(false, error.getResponse().getStatus(), error.getResponse().getReason()));
			}

		}

		private class MyHandler extends Handler {
			@Override
			public void handleMessage(Message msg) {
				switch (msg.what) {
				case EXITLOGINSUCCESS:
					L.v(TAG, " success : ", " 您的帐号已经在其他手机上登录，请重新登录 ");
					FoneUtil.showToast(ApplicationManage.getGlobalContext(), "您的帐号已经在其他手机上登录，请重新登录");
					Activity mActivity = ActivityQueue.popIndex(0);
					CallbackAdapter.this.callback.onSuccess((T) (msg.obj));
					if (mActivity != null && mActivity instanceof BaseActivity) {
						BaseActivity currentActivity = (BaseActivity) mActivity;
						currentActivity.distanceLoginCallback();// 回调异地登录方法
					}
					break;
				default:
					break;
				}
			}
		}
	}

	private static String TAG = Request.class.getName();

	private final Context context;
	private static Request sInstance, searchInstance, notifcationInstance;// searchInstance
	// 搜索时用，因为搜索接口用的端口与其他不同
	private String cipher, feeCipher;
	private String version;
	private String uid;
	private String shost;

	private final RestAdapter restAdapter;
	private final API api;

	interface API {

		/**
		 * 登录、升级接口: login?cipher=&ua=&nt=&uflag=
		 */
		@GET("/login")
		void login(@EncodedQuery("cipher") String cipher, @Query("ua") String ua, @Query("nt") String nt, @Query("uflag") int uflag, CallbackAdapter<LoginRst> callback);

		/**
		 * 首页接口 hotspot?cipher=&nt=&page=
		 */
		@GET("/hotspot")
		void hotspot(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, CallbackAdapter<HotspotRst> callback);

		/**
		 * 用户自定义频道设置接口 mnset?cipher=&ua=&nt=&seqid=
		 */

		@FormUrlEncoded
		@POST("/mnset")
		void mnset(@EncodedQuery("cipher") String cipher, @Query("ua") String ua, @Query("nt") String nt, @Field("data") String data, CallbackAdapter<Rst> callback);

		/**
		 * 栏目接口 specllist?clid=&cipher=&nt=&page=
		 */
		@GET("/{path}")
		void specllist(@EncodedPath("path") String path, CallbackAdapter<SpecllistRst> callback);
		
		/**
		 * 排行榜接口 topspot?clid=&cipher=&nt=&page=
		 */
		@GET("/{path}")
		void topspot(@EncodedPath("path") String path,
				CallbackAdapter<TopspotRst> callback);

		/**
		 * 视频详情页 vgdetail?cipher=&nt=&videoid=&cid=&ccid=
		 */
		@GET("/{path}")
		void vgdetail(@EncodedPath("path") String path, CallbackAdapter<VgdetailRst> callback);

		/**
		 * 播放、离线缓存接口 xyzplay?cid=&loop=&cipher=&nt=&ifp=&pt=&lk=&kw=&dfnt=
		 */
		@GET("/{path}")
		void xyzplay(@EncodedPath("path") String path, CallbackAdapter<XyzplaRst> callback);

		/**
		 * 播放、离线缓存接口 xyzplay?cid=&loop=&cipher=&nt=&ifp=&pt=&lk=&kw=&dfnt=
		 */
		@GET("/getvideoid")
		void sohuIds(@Query("ourl") String ourl, @EncodedQuery("cipher") String cipher, CallbackAdapter<SohuIdRst> callback);

		@GET("/{path}")
		XyzplaRst xyzplay(@EncodedPath("path") String path);

		/**
		 * 剧集接口 drama?ccid=&cipher=&nt=&f=&pt= &clid=&pclid=&page=
		 */
		@GET("/{path}")
		void drama(@EncodedPath("path") String path, CallbackAdapter<DramaRst> callback);

		/**
		 * 本地上报接口 replocal?cipher=&inf=
		 */
		@FormUrlEncoded
		@POST("/replocal")
		void replocal(@EncodedQuery("cipher") String cipher, @Query("fmt") String fmt, @Field("inf") String inf, CallbackAdapter<Rst> callback);

		/**
		 * 搜索接口 search?cipher=&type=&kw=&nt=&fmt=&p=&scope=
		 */
		@GET("/search")
		void search(@EncodedQuery("cipher") String cipher, @Query("type") int type, @Query("kw") String kw, @Query("nt") String nt, @Query("p") int page, @Query("fmt") String fmt, @Query("scope") String scope, @Query("dramaindex") String dramaindex, @Query("zhindex") String zhindex,
				@EncodedQuery("data") String data, CallbackAdapter<SearchRst> callback);

		/**
		 * 影讯通知及升级接口 qnt?cipher=&ua=&nt=&type=
		 */
		@GET("/qnt")
		void qnt(@EncodedQuery("cipher") String cipher, @Query("ua") String ua, @Query("nt") String nt, @Query("type") int type, CallbackAdapter<QntRst> callback);

		/**
		 * 软件下载及上报接口 dl?ccrid=&cipher=&nt=&flag=&pkid=
		 */
		@GET("/dl")
		void dl(@EncodedQuery("cipher") String cipher, @Query("ccrid") String ccrid, @Query("nt") String nt, @Query("flag") int flag, @Query("pkid") String pkid, CallbackAdapter<Rst> callback);

		/**
		 * 本地播放关联视频列表接口 rcmd?cipher=&nt=&page=
		 */
		@GET("/rcmd")
		void rcmd(@EncodedQuery("cipher") String cipher, @Query("page") int page, @Query("nt") String nt, CallbackAdapter<RcmdRst> callback);

		/**
		 * 关联视频列表接口（详情页面） linkvideo?cipher=&nt=&videoid=&clid=&ccid=&cid=&page=
		 */
		@GET("/{path}")
		void linkvideo(@EncodedPath("path") String path, CallbackAdapter<LinkvideoRst> callback);

		/**
		 * 关联视频列表接口（全屏播放界面）
		 * flinkvideo?cipher=&nt=&videoid=&clid=&ccid=&cid=&page=
		 */
		@GET("/{path}")
		void flinkvideo(@EncodedPath("path") String path, CallbackAdapter<FlinkvideoRst> callback);

		/**
		 * 热词接口 hotword?cipher=&nt=
		 */
		@GET("/hotword")
		void hotword(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, CallbackAdapter<HotwordRst> callback);

		/**
		 * 软件推荐接口 soft?cipher=&ua=&clid=&page=&nt=
		 */
		// @GET("/soft")
		// void soft(@EncodedQuery("cipher") String cipher, @Query("ua") String
		// ua, @Query("nt") String nt, CallbackAdapter<SoftRst> callback);

		@GET("/{path}")
		void soft(@EncodedPath("path") String path, CallbackAdapter<SoftRst> callback);

		/**
		 * 用户支付状态查询接口 us?cipher=
		 */
		@GET("/us")
		void us(@EncodedQuery("cipher") String cipher, @Query("type") String type, CallbackAdapter<UsRst> callback);

		/**
		 * 智能推荐-标签列表接口 label?cipher=&nt=&page=
		 */
		@GET("/label")
		void label(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("page") int page, CallbackAdapter<LabelRst> callback);

		/**
		 * 智能推荐-影片列表接口 tagcnts?cipher=&nt=&tagid=&page=
		 */
		@GET("/tagcnts")
		void tagcnts(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("page") int page, @Query("tagid") String tagid, @Query("ifp") int ifp, CallbackAdapter<TagcntsRst> callback);

		/**
		 * 100TV用户注册 regspace?cipher=&ua=&nt=&type=&comefrom=&data=
		 */
		@FormUrlEncoded
		@POST("/regspace")
		void regspace(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("ua") String ua, @Query("type") int type, @Query("comefrom") String comefrom, @Field("data") String data, CallbackAdapter<LoginspaceRst> callback);

		/**
		 * 绑定第三方帐号 binduser?cipher=&type=&data=
		 */
		@FormUrlEncoded
		@POST("/binduser")
		void binduser(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("flag") int flag, @Query("type") int type, @Field("data") String data, CallbackAdapter<Rst> callback);

		/**
		 * 用户登录/退出空间接口 loginspace?cipher=&ua=&type=&loadway=&ifp=&nt=
		 */
		@FormUrlEncoded
		@POST("/loginspace")
		void loginspace(@EncodedQuery("cipher") String cipher, @Query("ua") String ua, @Query("nt") String nt, @Query("type") int type, @Query("loadway") int loadway, @Query("ifp") int ifp, @Field("data") String data, CallbackAdapter<LoginspaceRst> callback);

		/**
		 * 修改用户密码、昵称 updateuser?cipher=&nt=&type=&oldvalue=&newvalue=
		 */
		@GET("/updateuser")
		void updateuser(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("type") int type, @Query("oldvalue") String oldvalue, @Query("newvalue") String newvalue, CallbackAdapter<Rst> callback);

		/**
		 * 帐户信息设置接口 updateuserinfo?cipher=&nt=&type=&age=&gender=&uerinfo=
		 */
		@GET("/updateuserinfo")
		void updateuserinfo(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("type") int type, @Query("age") int age, @Query("gender") int gender, @Query("userinfo") String userinfo, CallbackAdapter<Rst> callback);

		/**
		 * 头像修改接口 updatepic?cipher=&nt=&type=
		 */
		@FormUrlEncoded
		@POST("/updatepic")
		void updatepic(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("type") int type, @Field("pic") String pic, CallbackAdapter<UpdatepicRst> callback);

		/**
		 * 赞接口 like?cipher=&videoid=&nt=
		 */
		@GET("/like")
		void like(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("videoid") String videoid, @Query("ft") int ft, CallbackAdapter<Rst> callback);

		@FormUrlEncoded
		@POST("/collection")
		void collection(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Field("data") String data, @Query("flag") int flag, @Query("func") int func, @Query("tp") int tp, @Query("type") int type, CallbackAdapter<CollectionRst> callback);

		/**
		 * 取回收藏/播放记录接口 collectionls?cipher=&nt=&page=&func=
		 */
		@FormUrlEncoded
		@POST("/collectionls")
		void collectionls(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("page") int page, @Query("func") int func, @Field("data") String data, CallbackAdapter<CollectionlsRst> callback);

		/**
		 * 评论接口 comment?cipher=&videoid=&content=&nt=
		 */
		@GET("/{path}")
		void comment(@EncodedPath("path") String path, CallbackAdapter<Rst> callback);

		/**
		 * 反馈接口 fb?cipher=&nt=&cnt=&contact=&ctyp=
		 */
		@FormUrlEncoded
		@POST("/fb")
		void fb(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Field("cnt") String cnt, @Field("contact") String contact, @Field("ctyp") String ctyp, CallbackAdapter<Rst> callback);

		/**
		 * 获取用户评论接口 getusercomm?seqid=&page=&nt=
		 */
		@GET("/getusercomm")
		void getusercomm(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("cmtid") String cmtid, @Query("page") int page, CallbackAdapter<GetusercommRst> callback);

		/**
		 * 评论列表接口 commentlist?cipher=&page=&nt=&videoed=&tseqid=
		 */
		@GET("/{path}")
		void commentlist(@EncodedPath("path") String path, CallbackAdapter<CommentlistRst> callback);

		/**
		 * 虚拟币购买vip接口 consume?&cipher=
		 * &nt=wifi&orderid=130223198501205532&type=2
		 */
		@GET("/consume")
		void consume(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("ua") String ua, @Query("type") int type, @Query("orderid") String orderid, CallbackAdapter<Rst> callback);

		/**
		 * 上传视频接口 uploadvideo?cipher=&nt=&vpic=&url=&director=&actor=
		 */
		@GET("/uploadvideo")
		void uploadvideo(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("vpic") String vpic, @Query("vn") String vn, @Query("url") String url, @Query("director") String director, @Query("actor") String actor, @Query("summary") String summary, CallbackAdapter<Rst> callback);

		/**
		 * 删除视频接口 deletevideo?cipher=&nt=&videoid=
		 */
		@GET("/deletevideo")
		void deletevideo(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("videoid") String videoid, CallbackAdapter<Rst> callback);

		/**
		 * 大家看接口 see?cipher=&ua=&page=&nt=
		 */
		@GET("/see")
		void see(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("ua") String ua, @Query("page") int page, CallbackAdapter<SeeRst> callback);

		/**
		 * 大家看临时接口 see?cipher=&ua=&page=&nt=
		 */
		@GET("/see")
		void seetmp(@EncodedQuery("cipher") String cipher, @Query("mf") String mf, @Query("nt") String nt, @Query("ua") String ua, @Query("page") int page, CallbackAdapter<SeeRst> callback);

		/**
		 * 充值记录/消费记录 recordList?cipher=&ua=&nt=&type=
		 */
		@GET("/recordList")
		void recordList(@EncodedQuery("cipher") String cipher, @Query("ua") String ua, @Query("nt") String nt, @Query("type") int type, CallbackAdapter<RecordListRst> callback);

		/**
		 * vb查询接口 vb?cipher=
		 */
		@GET("/vb")
		void vb(@EncodedQuery("cipher") String cipher, CallbackAdapter<VbRst> callback);

		/**
		 * 网络播放接口 netplay?cipher=&url
		 */
		@GET("/netplay")
		void netplay(@EncodedQuery("cipher") String cipher, @Query("url") String url, CallbackAdapter<NetPlayRst> callback);

		/**
		 * airone投放接口
		 */
		@GET("/airone")
		void airone(@Query("c") String c, @Query("src") String src, @Query("ac") String ac, @Query("pc") String pc, @Query("wc") String wc, @Query("cs") String cs, @Query("cn") String cn, @Query("airone") String airone, @EncodedQuery("cipher") String cipher, CallbackAdapter<AironeRst> callback);

		/**
		 * 通知上报接口
		 */
		@FormUrlEncoded
		@POST("/rpqnt")
		void rpqnt(@EncodedQuery("cipher") String cipher, @Query("nt") String nt, @Query("fmt") String fmt, @Field("data") String data, @Field("notifyid") String notifyid, CallbackAdapter<Rst> callback);

		/* getindex?cipher= */
		@GET("/getindex")
		void getindex(@EncodedQuery("cipher") String cipher, retrofit.Callback<GetindexRst> callback);

		/* replocal?cipher=&inf= */
		@FormUrlEncoded
		@POST("/replocal")
		void replocal(@EncodedQuery("cipher") String cipher, @Query("fmt") String fmt, @Query("index") String index, @Field("inf") String inf, retrofit.Callback<Rst> callback);

		@FormUrlEncoded
		@POST("/playrep")
		void playrep(@EncodedQuery("cipher") String cipher, @Query("index") String index, @Field("inf") String inf, retrofit.Callback<Rst> callback);

		/* declaration?t=&cipher=&ua=&nt= */
		@GET("/declaration")
		void declaration(@EncodedQuery("cipher") String cipher, @Query("ua") String ua, @Query("nt") String nt, @Query("t") String t, retrofit.Callback<DeclarationRst> callback);
	}

	private Request(Context context) {
		if (context == null) {
			throw new IllegalArgumentException("Context must not be null.");
		}
		this.context = context.getApplicationContext();

		// Create a REST adapter which points the 100TV API
		// endpoint.
		restAdapter = new RestAdapter.Builder().setEndpoint(Configure.getEndPoint()).setLogLevel(LogLevel.FULL).setLog(new AndroidLog(TAG)).setConverter(new SimpleXMLConverter()).build();

		// Create an instance of our 100TV API interface.
		api = restAdapter.create(API.class);

		initCipher();
		initFeeCipher();
	}

	private Request(Context context, String path, Boolean isNotification) {
		if (context == null) {
			throw new IllegalArgumentException("Context must not be null.");
		}
		this.context = context.getApplicationContext();

		// Create a REST adapter which points the 100TV API
		// endpoint.

		if (isNotification) {
			restAdapter = new RestAdapter.Builder().setEndpoint(path).setLogLevel(LogLevel.FULL).setLog(new MyAndroidLog(TAG)).setConverter(new SimpleXMLConverter()).build();
		} else {
			restAdapter = new RestAdapter.Builder().setEndpoint(path).setLogLevel(LogLevel.FULL).setLog(new AndroidLog(TAG)).setConverter(new SimpleXMLConverter()).build();
		}
		// Create an instance of our 100TV API interface.
		api = restAdapter.create(API.class);

		initCipher();
		initFeeCipher();
	}

	public class MyAndroidLog extends AndroidLog {

		public MyAndroidLog(String tag) {
			super(tag);
		}

		@Override
		public void logChunk(String chunk) {
			super.logChunk(chunk);
			if (!TextUtils.isEmpty(chunk) && (chunk.startsWith("---> HTTP") || chunk.startsWith("<--- HTTP"))) {
				// 写入通知log文件
				FoneUtil.writeNotificationLog(FoneUtil.getTime() + "  " + chunk);
			}
		}
	}

	public static synchronized Request getSearchInstance(Context context) {
		if (searchInstance == null) {
			String path = Configure.getSearchPoint();
			searchInstance = new Request(context, path, false);
		}
		return searchInstance;
	}

	public static synchronized Request getNotifcationInstance(Context context) {
		if (notifcationInstance == null) {
			String path = Configure.getNotificationPoint();
			notifcationInstance = new Request(context, path, true);
		}
		return notifcationInstance;
	}

	public static synchronized void initializeInstance(Context context) {
		if (sInstance == null) {
			sInstance = new Request(context);
		}
	}

	public static synchronized Request getInstance() {
		if (sInstance == null) {
			throw new IllegalStateException(Request.class.getSimpleName() + " is not initialized, call initializeInstance(..) method first.");
		}
		return sInstance;
	}

	private void initCipher() {
		// cipher =
		// "pVkybguX6Mw8FSXoSLNfnok1AtFpU8fju1Gl7yoSoJNp3QxhCo37HIu50JD14F3QsOwXBo7wz5hduCIYW5n68Uy0C-cyKYBubtj_-24zltjDj8NU_P002h52xgFKy0xQ_FDBjV1RPi3vWRCZbiDLSVAByq-CrPaD_6oDOd3ZLJMj0l_MP17qgir-PFJWzCUAy7OlUpicjo2W_BRUYvRO3xDWMilcZP0P05Kjh5ALegs%3D";

		// loadCipherFromPreference();

		// 获取新的seqid
		String seqid = loadSeqidFromPreference();

		updateCipher(seqid);

		Log.i(TAG, "initCipher() load seqid form Preference. seqid=" + seqid);

	}

	private void initFeeCipher() {
		loadFeeCipherFromPreference();
		Log.i(TAG, "initFeeCipher() load cipher form Preference:" + feeCipher);
		if (feeCipher.length() == 0) {
			updateFeeCipher("");
		}
	}

	public void updateCipher(String seqid) {

		StringBuffer plaintext = new StringBuffer();

		if (null != seqid) {
			plaintext.append("seqid=" + seqid);
			saveSeqidToPreference(seqid);

		} else {
			plaintext.append("seqid=");
		}

		plaintext.append("&cv=" + getVersion());
		plaintext.append("&imei=" + getIMEI());
		plaintext.append("&imsi=" + getIMSI());
		plaintext.append("&uid=" + getUID());
		plaintext.append("&p=" + getPhoneNumber());
		plaintext.append("&pfv=android_" + getSDK());
		plaintext.append("&macadd=" + getMac());

		StringBuffer temp = new StringBuffer(plaintext);
		temp.append(Configure.getSlat());

		String md5 = toMD5(temp.toString());
		plaintext.append("&key=" + md5);

		Log.i(TAG, "updateCipher() before encrypt,  plaintext:" + plaintext);

		cipher = encrypt(Configure.getAesKey(), plaintext.toString());

		Log.i(TAG, "updateCipher() aftr encrypt, cipher:" + cipher);

		saveCipherToPreference();

	}

	public String updateFeeCipher(String seqid) {

		StringBuffer plaintext = new StringBuffer();

		plaintext.append("cv=" + getVersion());
		plaintext.append("&imei=" + getIMEI());
		plaintext.append("&imsi=" + getIMSI());
		plaintext.append("&uid=" + getUID());
		plaintext.append("&p=" + getPhoneNumber());

		StringBuffer temp = new StringBuffer(plaintext);
		temp.append(Configure.getFeeSlat());

		String md5 = toMD5(temp.toString());
		L.i(TAG, "key" + md5);
		plaintext.append("&key=" + md5);
		if (null != seqid) {
			plaintext.append("&seqid=" + seqid);
		} else {
			plaintext.append("&seqid=");
		}
		// plaintext.append("&seqid=" +
		// SharedPreferenceModule.getInstance().getString("seq_id"));

		Log.i(TAG, "getFeeCipher() before encrypt,  plaintext:" + plaintext);

		feeCipher = encrypt(Configure.getFeeAesKey(), plaintext.toString());

		Log.i(TAG, "getFeeCipher() aftr encrypt, cipher:" + feeCipher);
		saveFeeCipherToPreference();
		return feeCipher;
	}

	private String encrypt(String seed, String cleartext) {
		try {
			byte[] result = encrypt(seed.getBytes(), cleartext.getBytes());

			byte[] data = Base64.encode(result, Base64.URL_SAFE | Base64.NO_WRAP);
			String str = new String(data);
			return URLEncoder.encode(str, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}

		return "";
	}

	private byte[] encrypt(byte[] raw, byte[] clear) throws Exception {

		SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
		Cipher ci = Cipher.getInstance("AES");
		ci.init(Cipher.ENCRYPT_MODE, skeySpec);
		byte[] encrypted = ci.doFinal(clear);
		return encrypted;
	}

	private String loadSeqidFromPreference() {

		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
		return settings.getString("seqid", "");

	}

	private void saveSeqidToPreference(String seqid) {
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("seqid", seqid);
		editor.commit();

	}

	// private void loadCipherFromPreference() {
	//
	// SharedPreferences settings =
	// PreferenceManager.getDefaultSharedPreferences(context);
	// cipher = settings.getString("cipher", "");
	//
	// writeUID2File(getUID());//写入文件
	// }

	private void saveCipherToPreference() {
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("cipher", cipher);
		editor.commit();

	}

	private void loadFeeCipherFromPreference() {

		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
		feeCipher = settings.getString("feecipher", "");

	}

	private void saveFeeCipherToPreference() {
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString("feecipher", feeCipher);
		editor.commit();

	}

	public String toMD5(String str) {

		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");
			messageDigest.reset();
			messageDigest.update(str.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		byte[] byteArray = messageDigest.digest();
		StringBuffer md5StrBuff = new StringBuffer();
		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) {
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			} else {
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
			}
		}

		return md5StrBuff.toString();
	}

	public String getCipher() {
		return cipher;
	}

	public String getSHost() {
		return shost;
	}

	public void setSHost(String shost) {
		this.shost = shost;
	}

	public String getFeeCipher() {
		return feeCipher;
	}

	private String loadPhoneNumberFromFile() {
		String number = "";

		String path = context.getFilesDir().getAbsolutePath() + Configure.PHONE_NUMBER_FILE;

		File file = new File(path);

		if (file.exists() && file.isFile()) {
			try {

				FileInputStream fis = new FileInputStream(file);
				byte[] buffer = new byte[fis.available()];
				fis.read(buffer);
				fis.close();
				number = new String(buffer);

			} catch (Exception e) {
				e.printStackTrace();
			}

		} else {
			Log.i(TAG, "loadPhoneNumberFormFile() the file " + path + "doesn't exist.");
		}

		Log.i(TAG, "loadPhoneNumberFormFile() number:" + number);

		return number;
	}

	private String laodUserIdFromPreference() {

		SharedPreferences settings = context.getSharedPreferences(Configure.PREFS_NAME, 0);
		return settings.getString(Configure.USER_ID_KEY, "");

	}

	private void saveUserIdToPreference(String id) {

		SharedPreferences settings = context.getSharedPreferences(Configure.PREFS_NAME, 0);
		SharedPreferences.Editor editor = settings.edit();
		editor.putString(Configure.USER_ID_KEY, id);
		editor.commit();

	}

	private String getMac() {
		String macSerial = null;
		String str = "";
		try {
			Process pp = Runtime.getRuntime().exec("cat /sys/class/net/wlan0/address ");
			InputStreamReader ir = new InputStreamReader(pp.getInputStream());
			LineNumberReader input = new LineNumberReader(ir);
			for (; null != str;) {
				str = input.readLine();
				if (str != null) {
					macSerial = str.trim();
					break;
				}
			}
		} catch (IOException ex) {

			ex.printStackTrace();
		}

		return macSerial;
	}

	private String getIMEI() {

		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

		String imei = tm.getDeviceId();
		if (imei == null)
			imei = "";

		return imei;
	}

	private String getIMSI() {

		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		String imsi = tm.getSubscriberId();
		if (imsi == null)
			imsi = "";

		return imsi;
	}

	public String getUID() {

		if (uid != null) {
			return uid;
		}

		uid = laodUserIdFromPreference();// 从sp读取UID

		if (uid == null || uid.length() == 0) {

			uid = getUIDFromFile();// 从文件读取UID

			if (!TextUtils.isEmpty(uid)) {

				saveUserIdToPreference(uid);// 写入sp
			}

		}

		if (uid == null || uid.length() == 0) {

			int flag = (int) (Math.random() * 10);
			Time time = new Time();
			time.setToNow();

			long ms = System.currentTimeMillis();
			ms = ms % 1000;
			uid = String.format("%1$02d%2$02d%3$02d%4$02d%5$02d%6$02d%7$03d%8$01d0", time.year % 100, time.month + 1, time.monthDay, time.hour, time.minute, time.second, ms, flag % 10);

			saveUserIdToPreference(uid);// 写入sp

		}

		writeUID2File(uid);// 写入文件

		return uid;
	}

	/**
	 * 从文件获取UID
	 * 
	 * @return
	 */
	private String getUIDFromFile() {

		String idPath = Environment.getExternalStorageDirectory() + "/id_num.txt";
		File f = new File(idPath);
		if (f.isFile()) {
			if (f.canRead()) {
				FileInputStream fis = null;
				try {
					fis = new FileInputStream(f);
					byte[] bytes = new byte[100];
					int len = fis.read(bytes);
					fis.close();

					if (len == 17) {
						String g_id_string = new String(bytes, 0, len);
						return g_id_string;
					} else {

					}
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					if (fis != null) {
						try {
							fis.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		return "";
	}

	/**
	 * 将UID写入文件
	 * 
	 * @param UID
	 */
	private void writeUID2File(String UID) {

		if (UID != null && UID.length() > 0) {
			OutputStream fos = null;

			try {
				String idPath = Environment.getExternalStorageDirectory() + "/id_num.txt";
				File outputFile = new File(idPath);
				if (!outputFile.exists()) {
					fos = new FileOutputStream(outputFile);
					byte[] bt = UID.getBytes();
					fos.write(bt);
					fos.flush();
				}
			} catch (Exception e) {

			} finally {
				if (fos != null) {
					try {
						fos.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		}

	}

	private String getPhoneNumber() {

		String phoneNumber = "";

//		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//		if (tm != null && tm.getLine1Number() != null) {
//			phoneNumber = tm.getLine1Number();
//		}

		if (phoneNumber == null || phoneNumber.length() == 0) {
			phoneNumber = loadPhoneNumberFromFile();
		}

		return phoneNumber;

	}

	private String getVersion() {

		if (version == null) {
			try {
				AssetManager am = context.getAssets();
				DataInputStream dis = new DataInputStream(am.open("ver.txt"));
				byte[] buffer = new byte[dis.available()];
				dis.readFully(buffer);

				version = new String(buffer, "utf-8");
				dis.close();

			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return version;

	}

	private int getSDK() {
		return android.os.Build.VERSION.SDK_INT;
	}

	private String encodeData(Object data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {

		if (data == null) {
			return "";
		}

		Gson gson = new Gson();
		SecretKeySpec skeySpec = new SecretKeySpec(Configure.getAesKey().getBytes(), "AES");
		Cipher ci = Cipher.getInstance("AES");
		ci.init(Cipher.ENCRYPT_MODE, skeySpec);

		return new String(Base64.encode(ci.doFinal(gson.toJson(data).getBytes("UTF-8")), Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");

	}

	public String getNetworkType() {

		ConnectivityManager connectionManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

		NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();

		if (networkInfo == null) {
			return "";
		} else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {

			TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

			if (telephonyManager.getNetworkType() < 4) {
				return "gprs";

			} else if (telephonyManager.getNetworkType() == 13) {

				return "4g";

			} else {

				return "3g";
			}

		} else {
			return "wifi";
		}

	}

	/**
	 * 登录、升级接口
	 * 
	 * @param uflag
	 *            初始化类型: 0全部 1升级 2频道
	 * @param callback
	 */
	public void login(int uflag, Callback<LoginRst> callback) {

		CallbackAdapter<LoginRst> callbackAdapter = new CallbackAdapter<LoginRst>(callback);

		api.login(cipher, Configure.getUa(), getNetworkType(), uflag, callbackAdapter);

	}

	/**
	 * 首页接口
	 * 
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void hotspot(Callback<HotspotRst> callback) {

		CallbackAdapter<HotspotRst> callbackAdapter = new CallbackAdapter<HotspotRst>(callback);

		api.hotspot(cipher, getNetworkType(), callbackAdapter);

	}

	/**
	 * 用户自定义频道设置接口
	 * 
	 * @param seqid
	 *            用户id
	 * @param data
	 *            自定义的所有频道信息
	 * @param callback
	 */
	public void mnset(Object data, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		try {

			api.mnset(cipher, Configure.getUa(), getNetworkType(), encodeData(data), callbackAdapter);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 栏目接口
	 * 
	 * @param clid
	 *            栏目ID
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void specllist(String url, Callback<SpecllistRst> callback) {

		CallbackAdapter<SpecllistRst> callbackAdapter = new CallbackAdapter<SpecllistRst>(callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType();
		api.specllist(url, callbackAdapter);

	}
	
	/**
	 * 排行榜接口
	 * 
	 * @param clid
	 *            栏目ID
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void topspot(String url, Callback<TopspotRst> callback) {
		
		CallbackAdapter<TopspotRst> callbackAdapter = new CallbackAdapter<TopspotRst>(
				callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType();
		api.topspot(url, callbackAdapter);
		
	}

	/**
	 * 视频详情页
	 * 
	 * @param url
	 *            地址
	 * @param callback
	 * @return void
	 * @throws
	 */
	public void vgdetail(String url, Callback<VgdetailRst> callback) {

		CallbackAdapter<VgdetailRst> callbackAdapter = new CallbackAdapter<VgdetailRst>(callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType();
		api.vgdetail(url, callbackAdapter);

	}

	/**
	 * 播放、离线缓存接口
	 * 
	 * @param path
	 *            请求地址
	 * @param pt
	 *            播放类型信息 pt=1—播放 pt=2—下载 pt=3—下载成功上报
	 * @param comefrom
	 *            来源参考PlayerFrom类常量
	 * @param callback
	 *            请求回调
	 * @return void
	 * @throws
	 */
	public void xyzplay(String path, String pt, String comefrom, Callback<XyzplaRst> callback) {

		CallbackAdapter<XyzplaRst> callbackAdapter = new CallbackAdapter<XyzplaRst>(callback);
		path = path + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&fmt=xml" + "&pt=" + pt + "&comefrom=" + comefrom;

		api.xyzplay(path, callbackAdapter);
	}

	/**
	 * 获取搜狐视频相关id
	 * 
	 * @param ourl
	 *            原网页地址需要先Base64 再url
	 * @param callback
	 * @return void
	 * @throws
	 */
	public void getSohuIds(String ourl, Callback<SohuIdRst> callback) {
		CallbackAdapter<SohuIdRst> callbackAdapter = new CallbackAdapter<SohuIdRst>(callback);
		api.sohuIds(ourl, cipher, callbackAdapter);
	}

	/**
	 * 播放、离线缓存接口
	 * 
	 * @param cid
	 *            内容id
	 * @param loop
	 *            标识单条内容循环播放
	 * @param ifp
	 *            ifp=1 追剧列表进入 ifp=2 播放记录进入 ifp=3 栏目进入 ifp=4 剧集列表进入 ifp=5
	 *            全屏播放关联视频进入 ifp=6 首页进入 ifp=7 通知进入 ifp=8 分享进入 ifp=9 详情页关联视频进入
	 *            ifp=10 本地播放关联视频进入 ifp=11 详情页进入 ifp=12 栏目海报进入
	 * @param pt
	 *            播放类型信息 pt=1—播放 pt=2—下载 pt=3—下载成功上报
	 * @param lk
	 *            关联方式 lk=1—按栏目内容关联 lk=2—按搜索结果关联
	 * @param kw
	 *            可选参数，参数值base64加密，当lk=2时存在
	 * @param callback
	 * 
	 */

	public void xyzplay(String path, String pt, Callback<XyzplaRst> callback) {

		CallbackAdapter<XyzplaRst> callbackAdapter = new CallbackAdapter<XyzplaRst>(callback);
		path = path + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&fmt=xml" + "&pt=" + pt;

		api.xyzplay(path, callbackAdapter);
	}

	/**
	 * 播放、离线缓存接口
	 * 
	 * @param cid
	 *            内容id
	 * @param loop
	 *            标识单条内容循环播放
	 * @param ifp
	 *            ifp=1 追剧列表进入 ifp=2 播放记录进入 ifp=3 栏目进入 ifp=4 剧集列表进入 ifp=5
	 *            全屏播放关联视频进入 ifp=6 首页进入 ifp=7 通知进入 ifp=8 分享进入 ifp=9 详情页关联视频进入
	 *            ifp=10 本地播放关联视频进入 ifp=11 详情页进入 ifp=12 栏目海报进入
	 * @param pt
	 *            播放类型信息 pt=1—播放 pt=2—下载 pt=3—下载成功上报
	 * @param lk
	 *            关联方式 lk=1—按栏目内容关联 lk=2—按搜索结果关联
	 * @param kw
	 *            可选参数，参数值base64加密，当lk=2时存在
	 * @param callback
	 * 
	 */

	public XyzplaRst xyzplayDomain(String path, String pt) throws UnknownHostException, SocketTimeoutException {

		path = path + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&fmt=xml" + "&pt=" + pt;
		L.v(TAG, "xyzplay", "FN_CACHEMEDIA_REQ_URL cache path=" + path);
		return api.xyzplay(path);
	}

	/**
	 * 播放、离线缓存接口()
	 * 
	 * @param cid
	 *            内容id
	 * @param loop
	 *            标识单条内容循环播放
	 * @param ifp
	 *            ifp=1 追剧列表进入 ifp=2 播放记录进入 ifp=3 栏目进入 ifp=4 剧集列表进入 ifp=5
	 *            全屏播放关联视频进入 ifp=6 首页进入 ifp=7 通知进入 ifp=8 分享进入 ifp=9 详情页关联视频进入
	 *            ifp=10 本地播放关联视频进入 ifp=11 详情页进入 ifp=12 栏目海报进入
	 * @param pt
	 *            播放类型信息 pt=1—播放 pt=2—下载 pt=3—下载成功上报
	 * @param lk
	 *            关联方式 lk=1—按栏目内容关联 lk=2—按搜索结果关联
	 * @param kw
	 *            可选参数，参数值base64加密，当lk=2时存在
	 * @param callback
	 * 
	 */

	public XyzplaRst xyzplayIP(String path, String pt) {

		// Create a REST adapter which points the 100TV API
		// endpoint.
		RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint("http://211.151.137.39/vi/player").setLogLevel(LogLevel.FULL).setLog(new AndroidLog(TAG)).setConverter(new SimpleXMLConverter()).build();

		// Create an instance of our 100TV API interface.
		API api = restAdapter.create(API.class);

		path = path + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&fmt=xml" + "&pt=" + pt;
		L.v(TAG, "xyzplay", "FN_CACHEMEDIA_REQ_URL cache path=" + path);
		return api.xyzplay(path);
	}

	/**
	 * 剧集接口
	 * 
	 * @param ccid
	 *            内容集合ID
	 * @param f
	 *            f=4—详情页进入 f=15—从追剧列表进入 f=16—从搜索结果进入 f=17—从收藏进入
	 * @param pt
	 *            pt=2标识请求离线下载url报文
	 * @param clid
	 *            可选参数，剧集栏目ID
	 * @param pclid
	 *            可选参数，关联内容所在栏目ID
	 * @param page
	 *            页码
	 * @param callback
	 */

	public void drama(String url, Callback<DramaRst> callback) {

		CallbackAdapter<DramaRst> callbackAdapter = new CallbackAdapter<DramaRst>(callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType();
		api.drama(url, callbackAdapter);

	}

	/**
	 * 搜索接口
	 * 
	 * @param scope
	 *            搜索范围 0: 全部(默认) 1：片名 2演员和导演
	 * @param kw
	 *            搜索关键字
	 * @param page
	 *            页码
	 * @param callback
	 * 
	 */
	public void search(int type, String kw, int page, String scope, String dramaindex, String zhindex, Object data, Callback<SearchRst> callback) {
		Gson gson = new Gson();

		CallbackAdapter<SearchRst> callbackAdapter = new CallbackAdapter<SearchRst>(callback);
		try {
			api.search(cipher, type, kw, getNetworkType(), page, "xml", scope, dramaindex, zhindex, URLEncoder.encode(new String(Base64.encode(gson.toJson(data).getBytes("UTF-8"), Base64.URL_SAFE | Base64.NO_WRAP)), "UTF-8"), callbackAdapter);
		} catch (UnsupportedEncodingException e) {

			e.printStackTrace();
		}

	}

	/**
	 * 影讯通知
	 * 
	 * @param type
	 *            0 所有通知 1 计费通知
	 * @param callback
	 */
	public void qnt(int type, Callback<QntRst> callback) {

		initCipher();
		CallbackAdapter<QntRst> callbackAdapter = new CallbackAdapter<QntRst>(callback);
		api.qnt(cipher, Configure.getUa(), getNetworkType(), type, callbackAdapter);

	}

	/**
	 * 软件下载及上报接口
	 * 
	 * @param ccrid
	 *            栏目内容关联ID
	 * @param flag
	 *            下载或上报标识： 2 海报下载上报 3 安装包下载成功上报 4 安装包安装成功上报 5 游戏下载成功上报 6
	 *            游戏安装成功上报
	 * @param pkid
	 *            安装包id(flag为3,4,5,6时有值)
	 * @param callback
	 */
	public void dl(String ccrid, int flag, String pkid, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.dl(cipher, ccrid, getNetworkType(), flag, pkid, callbackAdapter);

	}

	/**
	 * 本地播放关联视频列表接口
	 * 
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void rcmd(int page, Callback<RcmdRst> callback) {
		CallbackAdapter<RcmdRst> callbackAdapter = new CallbackAdapter<RcmdRst>(callback);
		api.rcmd(cipher, page, getNetworkType(), callbackAdapter);

	}

	/**
	 * 关联视频列表接口（详情页面）
	 * 
	 * @param videoid
	 *            片库id
	 * @param clid
	 *            栏目id
	 * @param ccid
	 *            集合id
	 * @param cid
	 *            内容id
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void linkvideo(String path, Callback<LinkvideoRst> callback) {

		CallbackAdapter<LinkvideoRst> callbackAdapter = new CallbackAdapter<LinkvideoRst>(callback);
		path = path + "&cipher=" + cipher + "&nt=" + getNetworkType();
		api.linkvideo(path, callbackAdapter);

	}

	/**
	 * 关联视频列表接口（全屏播放界面）
	 * 
	 * @param videoid
	 *            片库id
	 * @param clid
	 *            栏目id
	 * @param ccid
	 *            集合id
	 * @param cid
	 *            内容id
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void flinkvideo(String path, Callback<FlinkvideoRst> callback) {
		CallbackAdapter<FlinkvideoRst> callbackAdapter = new CallbackAdapter<FlinkvideoRst>(callback);
		path = path + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&ua=" + Configure.getUa();
		api.flinkvideo(path, callbackAdapter);

	}

	/**
	 * 热词接口
	 * 
	 * @param callback
	 */
	public void hotword(Callback<HotwordRst> callback) {

		CallbackAdapter<HotwordRst> callbackAdapter = new CallbackAdapter<HotwordRst>(callback);
		api.hotword(cipher, getNetworkType(), callbackAdapter);

	}

	/**
	 * 软件推荐接口
	 * 
	 * @param callback
	 */
	public void soft(String url, Callback<SoftRst> callback) {
		CallbackAdapter<SoftRst> callbackAdapter = new CallbackAdapter<SoftRst>(callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&ua=" + Configure.getUa();
		api.soft(url, callbackAdapter);

	}

	/**
	 * 用户支付状态查询接口
	 * 
	 * @param type
	 *            标识页面： 0:付费提示 1：播放结束提示 2:普通提示 3:计费栏目提示有效期 4:详情页活动信息 5:确认下载
	 *            6：搜索法律申明 7：详情页法律申明 8：热点接口法律申明 9：剧集法律申明 10：栏目法律申明 11:
	 *            播放前提示(收费的视频，未计费用户,刚开始播的时候提示) 12: 直播法律申明 13: 权利人投诉申明 14: 计费成功通知
	 *            15:退出提示 16：自动注册提示 17：分享语 18：上传视频提示 19：注册条款及隐私声明 20：注册成功提示
	 *            21：注册页面底部付费信息 22：互动频道付费提示信息
	 * 
	 */

	public void us(String type, Callback<UsRst> callback) {
		CallbackAdapter<UsRst> callbackAdapter = new CallbackAdapter<UsRst>(callback);
		api.us(cipher, type, callbackAdapter);

	}

	/**
	 * 智能推荐-标签列表接口
	 * 
	 * @param page
	 *            页码
	 * @param callback
	 */
	public void label(int page, Callback<LabelRst> callback) {
		CallbackAdapter<LabelRst> callbackAdapter = new CallbackAdapter<LabelRst>(callback);
		api.label(cipher, getNetworkType(), page, callbackAdapter);

	}

	/**
	 * 智能推荐-影片列表接口
	 * 
	 * @param page
	 *            页码
	 * @param tagid
	 *            标签编号
	 * @param ifp
	 *            请求方式1点按钮2向下拉
	 * @param callback
	 */
	public void tagcnts(int page, String tagid, int ifp, Callback<TagcntsRst> callback) {
		CallbackAdapter<TagcntsRst> callbackAdapter = new CallbackAdapter<TagcntsRst>(callback);
		api.tagcnts(cipher, getNetworkType(), page, tagid, ifp, callbackAdapter);

	}

	/**
	 * 100TV用户注册
	 * 
	 * @param type
	 *            1：100TV主站用户
	 * @param comefrom
	 *            1 点击头像注册 2 点击立即充值 3 点击成为VIP 4 付费影片计费注册 5 其他
	 * @param data
	 *            第三方用户注册有效数据信息
	 * @param callback
	 */
	public void regspace(int type, String comefrom, Object data, Callback<LoginspaceRst> callback) {

		CallbackAdapter<LoginspaceRst> callbackAdapter = new CallbackAdapter<LoginspaceRst>(callback);

		try {
			api.regspace(cipher, getNetworkType(), Configure.getUa(), type, comefrom, encodeData(data), callbackAdapter);
		} catch (Exception e) {

			e.printStackTrace();
		}

	}

	/**
	 * 绑定第三方帐号
	 * 
	 * @param flag
	 *            1：绑定；0：取消绑定
	 * @param type
	 *            1：100TV主站用户；0：第三方用户；
	 * @param data
	 *            第三方用户注册有效
	 * @param callback
	 */
	public void binduser(int flag, int type, Object data, Callback<Rst> callback) {

		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);

		try {
			api.binduser(cipher, getNetworkType(), flag, type, encodeData(data), callbackAdapter);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 用户登录/退出空间接口
	 * 
	 * @param type
	 *            1：100TV主站用户； 0：第三方用户； 2：计费自动生成用户 3：获取最新用户信息 4：电视端登录 -1：退出空间
	 * @param loadway
	 *            1: 100tv; 2: QQ; 3: 新浪微博; 4:腾讯微博
	 * @param ifp
	 *            入口 60: 我的视频中“个人信息头像” 61: 点击我的视频中“加入VIP”按钮 62: 点击VIP频道中“加入VIP”
	 *            63: 点击计费权利页中“加入VIP” 64: 自动下发账号自动登录 65: 点击我的视频中“马上充值”按钮
	 * @param data
	 *            数据信息
	 * @param callback
	 */
	public void loginspace(int type, int loadway, int ifp, Object data, Callback<LoginspaceRst> callback) {

		CallbackAdapter<LoginspaceRst> callbackAdapter = new CallbackAdapter<LoginspaceRst>(callback);

		try {

			api.loginspace(cipher, Configure.getUa(), getNetworkType(), type, loadway, ifp, encodeData(data), callbackAdapter);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 修改用户密码、昵称
	 * 
	 * @param type
	 *            2：修改帐号（付费用户唯一一次） 1：密码修改(100TV录用户) 0：昵称修改（第三方用户）
	 * @param oldvalue
	 *            Base64(修改前值)
	 * @param newvalue
	 *            Base64(修改后值)
	 * @param callback
	 */
	public void updateuser(int type, String oldvalue, String newvalue, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.updateuser(cipher, getNetworkType(), type, oldvalue, newvalue, callbackAdapter);

	}

	/**
	 * 帐户信息设置接口
	 * 
	 * @param type
	 *            0：帐户信息设置
	 * @param age
	 *            年龄
	 * @param gender
	 *            性别 : 0:女 ; 1:男
	 * @param userinfo
	 *            用户个人简介
	 * @param callback
	 */
	public void updateuserinfo(int type, int age, int gender, String userinfo, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.updateuserinfo(cipher, getNetworkType(), type, age, gender, userinfo, callbackAdapter);

	}

	/**
	 * 更新头像接口 (空间背景 暂无)
	 * 
	 * @param type
	 *            修改类型 : 1 头像 2 空间背景
	 * @param pic
	 *            图片String (Base64)
	 * @param callback
	 */
	public void updatepic(int type, String pic, Callback<UpdatepicRst> callback) {
		CallbackAdapter<UpdatepicRst> callbackAdapter = new CallbackAdapter<UpdatepicRst>(callback);
		api.updatepic(cipher, getNetworkType(), type, pic, callbackAdapter);
	}

	/**
	 * 充值记录/消费记录
	 * 
	 * @param type
	 *            修改类型 : 1 消费记录 2 充值记录
	 * @param callback
	 */
	public void recordList(int type, Callback<RecordListRst> callback) {
		CallbackAdapter<RecordListRst> callbackAdapter = new CallbackAdapter<RecordListRst>(callback);
		api.recordList(cipher, Configure.getUa(), getNetworkType(), type, callbackAdapter);
	}

	/**
	 * vb余额查询
	 * 
	 * @param callback
	 */
	public void vb(Callback<VbRst> callback) {
		CallbackAdapter<VbRst> callbackAdapter = new CallbackAdapter<VbRst>(callback);
		api.vb(cipher, callbackAdapter);
	}

	/**
	 * 赞接口
	 * 
	 * @param videoid
	 *            视频ID
	 * @param ft
	 *            操作类型，2为取消赞，其它或空默认为添加赞
	 * @param callback
	 */
	public void like(String videoid, int ft, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.like(cipher, getNetworkType(), videoid, ft, callbackAdapter);

	}

	/**
	 * 收藏/播放记录接口
	 * 
	 * 
	 * @param data
	 *            内容集合
	 * @param flag
	 *            flag 标识:1添加 2取消 3 清空
	 * @param clid
	 *            可选参数，设置收藏的内容的栏目id
	 * @param func
	 *            函数功能类型：1 收藏2 播放记录3电视看
	 * @param tp
	 *            播放内容的时间点（秒），仅当func=2时可用，取值为999999时代表播放结束（播放记录只有在切换视频或播
	 *            客户端放结束时上报）
	 * @param type
	 *            内容类型(0 全部1电影2电视剧3动漫4综艺5原创6视频直播7音频直播8新闻9短片)
	 * @param callback
	 */
	public void collection(Object data, int flag, int func, int tp, int type, Callback<CollectionRst> callback) {

		CallbackAdapter<CollectionRst> callbackAdapter = new CallbackAdapter<CollectionRst>(callback);
		try {
			api.collection(cipher, getNetworkType(), encodeData(data), flag, func, tp, type, callbackAdapter);
		} catch (Exception e) {
			e.printStackTrace();

		}
	}

	/**
	 * 取回收藏/播放记录接口
	 * 
	 * @param page
	 *            页码
	 * @param func
	 *            函数功能类型：1取回收藏2 取回播放记录3取回电视看
	 * @param data
	 * @param callback
	 */
	public void collectionls(int page, int func, Object data, Callback<CollectionlsRst> callback) {
		CallbackAdapter<CollectionlsRst> callbackAdapter = new CallbackAdapter<CollectionlsRst>(callback);
		try {
			api.collectionls(cipher, getNetworkType(), page, func, encodeData(data), callbackAdapter);
		} catch (Exception e) {
			e.printStackTrace();

		}

	}

	/**
	 * 评论接口
	 * 
	 * @param videoid
	 *            视频ID
	 * @param content
	 *            评论内容
	 * @param callback
	 */
	public void comment(String url, String content, Callback<Rst> callback) {

		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType() + "&content=" + content;
		api.comment(url, callbackAdapter);

	}

	/**
	 * 获取用户评论接口
	 * 
	 * @param cmtid
	 *            被获取的用户ID
	 * @param page
	 *            第几页
	 * @param callback
	 */
	public void getusercomm(String cmtid, int page, Callback<GetusercommRst> callback) {
		CallbackAdapter<GetusercommRst> callbackAdapter = new CallbackAdapter<GetusercommRst>(callback);
		api.getusercomm(cipher, getNetworkType(), cmtid, page, callbackAdapter);

	}

	/**
	 * 获取用户评论接口
	 * 
	 * @param cnt
	 *            反馈内容
	 * @param contact
	 *            联系方式
	 * @param ctyp
	 *            联系方式类型
	 * @param callback
	 */
	public void fb(String cnt, String contact, String ctyp, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.fb(cipher, getNetworkType(), cnt, contact, ctyp, callbackAdapter);
	}

	/**
	 * 评论列表接口
	 * 
	 * @param videoid
	 *            片库id
	 * @param page
	 *            页码
	 * @param tseqid
	 *            seqid
	 * @param callback
	 */
	public void commentlist(String url, Callback<CommentlistRst> callback) {

		CallbackAdapter<CommentlistRst> callbackAdapter = new CallbackAdapter<CommentlistRst>(callback);
		url = url + "&cipher=" + cipher + "&nt=" + getNetworkType();
		api.commentlist(url, callbackAdapter);

	}

	/**
	 * 虚拟币购买vip接口
	 * 
	 * @param type
	 *            1，购买vip，2，购买虚拟币
	 * @param orderid
	 *            购买流水
	 * @param callback
	 */
	public void consume(int type, String orderid, Callback<Rst> callback) {

		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.consume(cipher, getNetworkType(), Configure.getUa(), type, orderid, callbackAdapter);

	}

	/**
	 * 上传视频接口
	 * 
	 * @param vpic
	 *            海报信息BASE64处理
	 * @param vn
	 *            视频名称
	 * @param url
	 *            视频地址
	 * @param director
	 *            导演
	 * @param actor
	 *            演员
	 * @param summary
	 *            简介
	 * @param callback
	 */
	public void uploadvideo(String vpic, String vn, String url, String director, String actor, String summary, Callback<Rst> callback) {

		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.uploadvideo(cipher, getNetworkType(), vpic, vn, url, director, actor, summary, callbackAdapter);

	}

	/**
	 * 删除视频接口
	 * 
	 * @param videoid
	 *            视频id(视频标识)
	 * @param callback
	 */
	public void deletevideo(String videoid, Callback<Rst> callback) {
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		api.deletevideo(cipher, getNetworkType(), videoid, callbackAdapter);

	}

	/**
	 * 大家看接口
	 * 
	 * @param page
	 *            页码 不传默认为第一页
	 * @param callback
	 */
	public void see(int page, Callback<SeeRst> callback) {

		CallbackAdapter<SeeRst> callbackAdapter = new CallbackAdapter<SeeRst>(callback);
		api.see(cipher, getNetworkType(), Configure.getUa(), page, callbackAdapter);

	}

	/**
	 * 大家看接口
	 * 
	 * @param page
	 *            页码 不传默认为第一页
	 * @param callback
	 */
	public void seeTmp(int page, int mf, Callback<SeeRst> callback) {

		CallbackAdapter<SeeRst> callbackAdapter = new CallbackAdapter<SeeRst>(callback);
		api.seetmp(cipher, "1", getNetworkType(), Configure.getUa(), page, callbackAdapter);

	}

	/**
	 * 通知上报接口
	 * 
	 * @param page
	 *            页码 不传默认为第一页
	 * @param callback
	 */
	public void rpqnt(String data, String notifyid, Callback<Rst> callback) {
		initCipher();
		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);
		try {
			data = new String(Base64.encode(data.getBytes("UTF-8"), Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
			notifyid = new String(Base64.encode(notifyid.getBytes("UTF-8"), Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
			api.rpqnt(cipher, getNetworkType(), "xml", data, notifyid, callbackAdapter);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			L.e(TAG, "rpqnt", e.getMessage());
		}
	}

	/**
	 * 提示语接口
	 * 
	 * @param t
	 *            数字 用","隔开 例: 1,2
	 * @param callback
	 */
	// <option value="0">付费提示</option>
	// <option value="1">播放结束提示</option>
	// <option value="2">普通提示</option>
	// <option value="3">计费栏目提示有效期</option>
	// <option value="4">详情页活动信息</option>
	// <option value="5">确认下载</option>
	// <option value="6">搜索法律申明</option>
	// <option value="7">详情页法律申明</option>
	// <option value="8">热点接口法律申明</option>
	// <option value="9">剧集法律申明</option>
	// <option value="10">栏目法律申明</option>
	// <option value="11">付费正片开始提示</option>
	// <option value="12">直播法律申明</option>
	// <option value="13">设置里的申明</option>
	// <option value="14">计费成功通知</option>
	// <option value="15">退出提示</option>
	// <option value="16">自动注册提示</option>
	// <option value="17">分享语</option>
	// <option value="18">上传视频法律声明</option>
	// <option value="19">注册条款及隐私声明</option>
	// <option value="20">注册成功提示</option>
	// <option value="21">注册页底部付费信息</option>
	// <option value="22">互动频道付费提示</option>
	// <option value="23">互动频道付费成功提示</option>
	// <option value="24">付费成功提示</option>
	public void declaration(String t, Callback<DeclarationRst> callback) {

		CallbackAdapter<DeclarationRst> callbackAdapter = new CallbackAdapter<DeclarationRst>(callback);
		api.declaration(cipher, Configure.getUa(), getNetworkType(), t, callbackAdapter);

	}

	/**
	 * 网路播放
	 * 
	 * @param url
	 *            需要aes base64加密
	 * @param callback
	 */
	public void netplay(String url, Callback<NetPlayRst> callback) {

		CallbackAdapter<NetPlayRst> callbackAdapter = new CallbackAdapter<NetPlayRst>(callback);
		SecretKeySpec skeySpec = new SecretKeySpec(Configure.getAesKey().getBytes(), "AES");
		try {
			Cipher ci = Cipher.getInstance("AES");
			ci.init(Cipher.ENCRYPT_MODE, skeySpec);

			url = new String(Base64.encode(ci.doFinal(url.getBytes("UTF-8")), Base64.URL_SAFE | Base64.NO_WRAP), "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();

		}
		api.netplay(cipher, url, callbackAdapter);

	}

	/**
	 * pc 投放
	 * 
	 * @param page
	 *            页码 不传默认为第一页
	 * @param callback
	 */
	public void airone(String aircode, Callback<AironeRst> callback) {
		CallbackAdapter<AironeRst> callbackAdapter = new CallbackAdapter<AironeRst>(callback);
		api.airone("2", "aHR0cDovLzIxOC4yNDAuMTkuMjYvdmlkZW9zL3R2LzIwMTMwNTA1L2Y0ZWZkZjA0YmVmYWEyOTBjZWQ5ZjQ4YWM3ODMzMDA5Lm1wND9rZXk9ZDQ4YjQ3ODExMzBjZmE1OCZ1dWlkPTk1ZWE3N2E2NzMxODQ3ZGU4NDU0MzJiMjhmMjI1YWIx", "100", "0-11-54", "0", "0", "6ZmG6LSe5Lyg5aWHMDE%3D", aircode, getCipher(), callbackAdapter);
	}

	public void getindex(Callback<GetindexRst> callback) {

		CallbackAdapter<GetindexRst> callbackAdapter = new CallbackAdapter<GetindexRst>(callback);
		api.getindex(cipher, callbackAdapter);
	}

	public void replocal(String inf, String index, Callback<Rst> callback) {

		Log.v("Reporter", "replocal inf: " + inf + " index: " + index);

		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);

		api.replocal(cipher, "xml", index, inf, callbackAdapter);
	}

	public void playrep(String inf, String index, Callback<Rst> callback) {

		Log.v("Reporter", "playrep inf: " + inf + " index: " + index);

		CallbackAdapter<Rst> callbackAdapter = new CallbackAdapter<Rst>(callback);

		api.playrep(cipher, index, inf, callbackAdapter);
	}

}
